﻿using Aribaccio;
using Aribaccio.Device;
using Aribaccio.Logger;
using BDPAutodetect.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BDPAutodetect.Simcore
{
    public class DeviceSimulatorElectrical : DeviceSimulatorModbus
    {
        /// <summary>
        /// 设备仿真数据
        /// </summary>
        protected Dictionary<DeviceModule, DeviceSimulatorDataElectrical> DeviceSimulatorDataDict { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="argDevice">设备连接对象</param>
        /// <param name="argTargetSlaves">设备指标协议数据集</param>
        public DeviceSimulatorElectrical(DeviceSerialModbus<IDevicePara> argDevice)
            : base($"电压电流采样板仿真设备", DeviceType.Electrical, DeviceModule.None, argDevice)
        {
            this.DeviceSimulatorDataDict = new Dictionary<DeviceModule, DeviceSimulatorDataElectrical>();
        }

        /// <summary>
        /// 接收设备数据解析
        /// </summary>
        /// <returns></returns>
        protected override DeviceCommandData? DeviceDataParse(ModbusSlaveData<StructInputShort> argModbusData, string argModbusDataHex)
        {
            var commandData = base.DeviceDataParse(argModbusData, argModbusDataHex);
            if (commandData == null) return commandData;
            //检测是否存在字典
            if (!this.DeviceSimulatorDataDict.ContainsKey(commandData.DeviceModule))
            {
                this.DeviceSimulatorDataDict.Add(commandData.DeviceModule, new DeviceSimulatorDataElectrical(commandData.DeviceModule));
            }
            //获取仿真数据实例
            var simulatorData = this.DeviceSimulatorDataDict[commandData.DeviceModule];
            switch (commandData.DeviceTargetType)
            {
                case DeviceTargetType.Electrical_CurrentRead:
                    simulatorData.CalculateCurrent();
                    break;
                case DeviceTargetType.Electrical_VoltageRead:
                    simulatorData.CalculateVoltage();
                    break;
            }
            return commandData;
        }

        /// <summary>
        /// 设备数据响应解析
        /// </summary>
        /// <param name="argCommandData"></param>
        protected override byte[] DeviceDataResponseParse(DeviceCommandData argCommandData)
        {
            List<byte> responseBytes = new List<byte>();
            //获取响应指令
            var CommandBytes = base.DeviceDataResponseParse(argCommandData);
            responseBytes.AddRange(CommandBytes);
            //获取数据
            var simulatorData = this.DeviceSimulatorDataDict[argCommandData.DeviceModule];          
            ushort nDataValue = 0;
            switch (argCommandData.DeviceTargetType)
            {
                case DeviceTargetType.Electrical_CurrentRead:
                    //nDataValue = 98;
                    nDataValue = (ushort)simulatorData.Current;
                    break;
                case DeviceTargetType.Electrical_VoltageRead:
                    //nDataValue = 2200;
                    nDataValue = (ushort)simulatorData.Voltage;
                    break;
                case DeviceTargetType.Electrical_PowerRead:
                    //nDataValue = 110;
                    nDataValue = (ushort)simulatorData.GetPower();
                    break;
            }
            responseBytes.Add(2);
            responseBytes.AddRange(nDataValue.StructToBytes());
            //计算CRC
            var crcBytes = responseBytes.ToArray().ToCheckCRCModbus();
            responseBytes.AddRange(crcBytes);
            return responseBytes.ToArray();
        }
    }

    /// <summary>
    /// 仿真数据
    /// </summary>
    public class DeviceSimulatorDataElectrical
    {
        private long currentDivisor = 0;
        private long voltageDivisor = 0;
        private Random random = new Random();

        /// <summary>
        /// 设备指标模组
        /// </summary>
        public DeviceModule Module { get; set; }
        /// <summary>
        /// 电流（单位0.01A = 10mA）
        /// </summary>
        public int Current { get; protected set; }
        /// <summary>
        /// 电压（单位0.1V = 100mV）
        /// </summary>
        public int Voltage { get; protected set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public DeviceSimulatorDataElectrical(DeviceModule argModule)
        {
            this.Module = argModule;
        }

        public void CalculateCurrent()
        {
            if (this.currentDivisor != 0 && this.currentDivisor > this.voltageDivisor) return;
            //0.98A - 1.5A
            this.Current = random.Next(98, 15 * 10);
            this.currentDivisor++;
            if (this.currentDivisor >= (long.MaxValue - 1))
            {
                this.currentDivisor = 0;
            }
        }

        public void CalculateVoltage()
        {
            if (this.voltageDivisor != 0 && this.voltageDivisor > this.currentDivisor) return;
            //215V - 225V
            this.Voltage = random.Next(215 * 10, 225 * 10);
            this.voltageDivisor++;
            if (this.voltageDivisor >= (long.MaxValue - 1))
            {
                this.voltageDivisor = 0;
            }
        }

        public int GetPower()
        {
            if (this.currentDivisor == 0 && this.voltageDivisor == 0)
            {
                this.CalculateVoltage();
                this.CalculateCurrent();
            }
            else
            {
                if (this.currentDivisor > this.voltageDivisor)
                {
                    this.CalculateVoltage();
                    this.voltageDivisor = this.currentDivisor;
                }
                else if (this.currentDivisor < this.voltageDivisor)
                {
                    this.CalculateCurrent();
                    this.currentDivisor = this.voltageDivisor;
                }
            }
            double dCos = random.Next(60, 80) * 0.01;
            //功率（W）= 电流（A） * 电压（V） * 因素（F）
            return (int)Math.Round((this.Current * 0.01) * (this.Voltage * 0.1) * dCos);
        }
    }
}
